﻿using System;
using System.ComponentModel;
using DataService.Enums;
using DataService.Structs;
using DataService.Tag;

namespace DataService;

public abstract class SimpleCondition : ConditionBase, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public override string Value
        => _tag == null ? null : _tag.ToString();

    protected TagBase _tag;
    public TagBase Tag
    {
        get => _tag;
        set
        {
            if (_tag != null)
                _tag.ValueChanging -= CheckAlarm;
            _tag = value;
            if (_tag != null)
                _tag.ValueChanging += CheckAlarm;
        }
    }

    protected SimpleCondition(int id, ConditionType conditionType, string source, string comment, float para, float deadBand, int delay) :
        base(id, conditionType, source, comment, para, deadBand, delay)
    { }

    protected override void OnActive(SubCondition condition, Storage value, DateTime timeStamp)
    {
        if (condition.SubAlarmType != ActiveSubCondition)
        {
            if (condition.SubAlarmType != _tempType)
            {
                _timeStamp = timeStamp;
                _tempType = condition.SubAlarmType;
            }
            if (_delay == 0 || (timeStamp - _timeStamp).TotalMilliseconds > _delay)
            {
                if (ActiveSubCondition == SubAlarmType.None)
                {
                    _active = true;
                    _condLastActive = timeStamp;
                }
                _ack = false;
                ActiveSubCondition = condition.SubAlarmType;
                _current.Duration = timeStamp - SubCondLastActive;
                _current = new AlarmItem(timeStamp, condition.Message, _tag.GetValue(value), ActiveSubCondition, condition.Severity, _id, _source);
                if (AlarmActive != null)
                {
                    foreach (AlarmEventHandler deleg in AlarmActive.GetInvocationList())
                    {
                        deleg.BeginInvoke(this, _current, null, null);
                    }
                }
                RaiseChanged("Value");
            }
        }
        else
        {
            RaiseChanged("Value");
        }
    }

    protected override void OnInActive(Storage value)
    {
        if (ActiveSubCondition != SubAlarmType.None)
        {
            _active = false;
            ActiveSubCondition = SubAlarmType.None;
            _current.Duration = DateTime.Now - SubCondLastActive;
            _current = new AlarmItem(DateTime.Now, string.Concat("【", _current.AlarmText, "】", ALARMSTOP), _tag.GetValue(value), SubAlarmType.None, Severity.Normal, _id, _source);
            if (AlarmActive != null)
            {
                foreach (AlarmEventHandler deleg in AlarmActive.GetInvocationList())
                {
                    deleg.BeginInvoke(this, _current, null, null);
                }
            }
        }
    }

    protected void RaiseChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }

    public override void Dispose()
    {
        base.Dispose();
        PropertyChanged = null;
        if (_tag != null)
            _tag.ValueChanging -= CheckAlarm;
    }

    protected abstract void CheckAlarm(object sender, ValueChangingEventArgs<Storage> e);

    public override AlarmType AlarmType => AlarmType.None;

    public override bool AddSubCondition(SubCondition condition)
    {
        return true;
    }

    public override bool RemoveSubCondition(SubCondition condition)
    {
        return true;
    }
}
